package com.idea.dsl.service;

import com.idea.dsl.client.ModelClient;
import com.idea.dsl.client.ModelClientFactory;
import com.idea.dsl.config.DslProperties;
import com.idea.dsl.model.DslRequest;
import com.idea.dsl.model.DslResponse;
import com.idea.dsl.model.ModelRequest;
import com.idea.dsl.model.ModelResponse;
import com.idea.dsl.model.*;
import com.idea.dsl.template.TemplateManager;
import com.idea.dsl.validator.DslValidator;
import com.idea.dsl.validator.DslValidatorFactory;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.UUID;

/**
 * DSL生成服务
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class DslGeneratorService {
    
    private final ModelClientFactory modelClientFactory;
    private final TemplateManager templateManager;
    private final DslValidatorFactory validatorFactory;
    private final DslProperties dslProperties;
    
    /**
     * 生成DSL
     * 
     * @param request 生成请求
     * @return 生成响应
     */
    public DslResponse generateDsl(DslRequest request) {
        long startTime = System.currentTimeMillis();
        String requestId = UUID.randomUUID().toString();
        
        log.info("开始生成DSL, requestId: {}, dslType: {}", requestId, request.getDslType());
        
        try {
            // 1. 参数验证和预处理
            preprocessRequest(request);
            
            // 2. 生成提示词
            String prompt = templateManager.generatePrompt(request);
            
            // 3. 调用大模型
            String modelType = StringUtils.isNotBlank(request.getModel()) 
                ? request.getModel() 
                : dslProperties.getGenerator().getDefaultModel();
            
            ModelClient client = modelClientFactory.getClient(modelType);
            ModelRequest modelRequest = buildModelRequest(request, prompt);
            ModelResponse modelResponse = client.chat(modelRequest);
            
            // 4. 提取DSL内容
            String dslContent = extractDslContent(modelResponse);
            
            // 5. 验证DSL
            DslResponse.ValidationResult validation = validateDsl(dslContent, request);
            
            // 6. 构建响应
            long duration = System.currentTimeMillis() - startTime;
            DslResponse.GenerationStatus status = determineStatus(validation);
            
            DslResponse response = DslResponse.builder()
                    .requestId(requestId)
                    .dslContent(dslContent)
                    .dslType(request.getDslType())
                    .model(modelType)
                    .status(status)
                    .validation(validation)
                    .generatedAt(LocalDateTime.now())
                    .duration(duration)
                    .build();
            
            log.info("DSL生成完成, requestId: {}, status: {}, duration: {}ms", 
                requestId, status, duration);
            
            return response;
            
        } catch (Exception e) {
            log.error("DSL生成失败, requestId: " + requestId, e);
            
            long duration = System.currentTimeMillis() - startTime;
            return DslResponse.builder()
                    .requestId(requestId)
                    .dslType(request.getDslType())
                    .status(DslResponse.GenerationStatus.FAILED)
                    .errorMessage(e.getMessage())
                    .generatedAt(LocalDateTime.now())
                    .duration(duration)
                    .build();
        }
    }
    
    /**
     * 预处理请求参数
     */
    private void preprocessRequest(DslRequest request) {
        // 设置默认参数
        if (request.getParams() == null) {
            request.setParams(DslRequest.GenerationParams.builder()
                    .maxTokens(dslProperties.getGenerator().getMaxTokens())
                    .temperature(dslProperties.getGenerator().getTemperature())
                    .validate(true)
                    .build());
        }
        
        // 参数校验
        if (StringUtils.isBlank(request.getDescription())) {
            throw new IllegalArgumentException("需求描述不能为空");
        }
        
        if (StringUtils.isBlank(request.getDslType())) {
            throw new IllegalArgumentException("DSL类型不能为空");
        }
    }
    
    /**
     * 构建模型请求
     */
    private ModelRequest buildModelRequest(DslRequest request, String prompt) {
        return ModelRequest.builder()
                .messages(Arrays.asList(
                    ModelRequest.Message.builder()
                        .role("user")
                        .content(prompt)
                        .build()
                ))
                .model(request.getModel())
                .maxTokens(request.getParams().getMaxTokens())
                .temperature(request.getParams().getTemperature())
                .stream(false)
                .build();
    }
    
    /**
     * 提取DSL内容
     */
    private String extractDslContent(ModelResponse response) {
        if (response.getChoices() == null || response.getChoices().isEmpty()) {
            throw new RuntimeException("模型响应为空");
        }
        
        ModelRequest.Message message = response.getChoices().get(0).getMessage();
        if (message == null || StringUtils.isBlank(message.getContent())) {
            throw new RuntimeException("模型响应内容为空");
        }
        
        return message.getContent().trim();
    }
    
    /**
     * 验证DSL
     */
    private DslResponse.ValidationResult validateDsl(String dslContent, DslRequest request) {
        if (request.getParams().getValidate() == null || !request.getParams().getValidate()) {
            return DslResponse.ValidationResult.builder()
                    .valid(true)
                    .syntaxValid(true)
                    .semanticValid(true)
                    .build();
        }
        
        DslValidator validator = validatorFactory.getValidator(request.getDslType());
        if (validator == null) {
            log.warn("未找到DSL类型 {} 的验证器", request.getDslType());
            return DslResponse.ValidationResult.builder()
                    .valid(true)
                    .syntaxValid(true)
                    .semanticValid(true)
                    .build();
        }
        
        return validator.validate(dslContent, request.getDslType());
    }
    
    /**
     * 确定生成状态
     */
    private DslResponse.GenerationStatus determineStatus(DslResponse.ValidationResult validation) {
        if (validation == null || validation.getValid()) {
            return DslResponse.GenerationStatus.SUCCESS;
        }
        
        if (validation.getSyntaxValid() && !validation.getSemanticValid()) {
            return DslResponse.GenerationStatus.PARTIAL;
        }
        
        return DslResponse.GenerationStatus.VALIDATION_FAILED;
    }
}
